package com.neusoft.dao;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class BaseDao<T> {
	/**
	 * 	获取数据库连接
	 * @return
	 */
	protected Connection getConn() {
		Connection conn = null;
		//1、准备数据库用户名、密码、url、driver
		String username = "root";
		String password = "root";
		String driver = "com.mysql.jdbc.Driver";
		//协议://地址:端口号/数据库名?连接属性设置
		String url = "jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&useSSL=false";
		
		try {
			//加载驱动类到虚拟机中
			Class.forName(driver);//这是属于反射的内容
			//获取数据库连接java.sql.Connection
			conn = DriverManager.getConnection(url, username, password);
			System.out.println(conn);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return conn;
	}
	
	/**
	 * 	关闭数据库连接
	 * @param rs
	 * @param st
	 * @param conn
	 */
	protected void close(ResultSet rs, Statement st, Connection conn) {
		if(rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if(st != null) {
			try {
				st.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if(conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 	增删改的实现代码
	 * @param sql
	 * @param args
	 * @return
	 */
	protected boolean doIUD(String sql, Object... args) {
		Connection conn = getConn();
		//准备SQL命令
		PreparedStatement st = null;//可以防止sql注入攻击
		try {
			//通过数据库连接conn获取事务java.sql.Statement对象st
			st = conn.prepareStatement(sql);
			if(args != null && args.length != 0) {
				for(int i = 0; i < args.length; i++) {
					st.setObject(i + 1, args[i]);
				}
			}
			//执行sql命令
			int row = st.executeUpdate();
			
			return row > 0;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close(null, st, conn);
		}
		
		return false;
	}

	/**
	 * 查询一条或多条
	 * @param sql
	 * @param cls
	 * @param list	查询多条时，必传
	 * @param args
	 * @return	查询一条时，返回对象
	 */
	public <T> T query(String sql, Class cls, List<T> list, Object... args) {
		Connection conn = getConn();
		PreparedStatement st = null;//可以防止sql注入攻击
		ResultSet rs = null;
		T bean = null;
		try {
			//通过数据库连接conn获取事务java.sql.Statement对象st
			st = conn.prepareStatement(sql);
			if(args != null && args.length != 0) {
				for(int i = 0; i < args.length; i++) {
					st.setObject(i + 1, args[i]);
				}
			}
			//执行sql命令
			rs = st.executeQuery();
			//处理查询结果集
			while(rs.next()) {
				try {
					bean = (T) cls.newInstance();//通过调用默认无参构造方法创建对象
					//通过反射获取所有属性
					Field[] fs = cls.getDeclaredFields();
					for (Field item : fs) {
						item.setAccessible(true);
						item.set(bean, rs.getObject(camel2_(item.getName())));
					}
					//通过数据库的相关类获取表的所有列名
				} catch (Exception e) {
					e.printStackTrace();
				}
				if (list != null) {
					list.add(bean);
				}else {
					break;
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close(rs, st, conn);
		}

		return bean;
	}

	public String camel2_(String str) {
		Pattern pattern = Pattern.compile("[A-Z]");
		Matcher matcher = pattern.matcher(str);
		StringBuffer sb = new StringBuffer();
		while (matcher.find()) {
			matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
		}
		matcher.appendTail(sb);
		return sb.toString();
	}
}
